package org.oep.jmingle;

import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Font;

import java.io.IOException;
import java.util.Vector;

public class IDWidget {
	private Vector subjects = new Vector();
	private Image subject;
	private Image basePortrait;
	private MingleTracker tracker;
	
	private Image arrowLeft;
	private Image arrowRight;
	
	private String friendlyLastSeen;
	private int x,y;
	private int width = 125, height = 100;
	private int elementIndex = 0;
	private boolean active = false;
	
	IDWidget(int x, int y, int width, int height) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		
		loadImages();
	}
	
	
	private void loadImages() {
		try {
			arrowLeft = Image.createImage("/res/graphics/arrow-left.png");
			arrowRight = Image.createImage("/res/graphics/arrow-right.png");
		}
		catch(IOException e) {
			arrowLeft = null;
			arrowRight = null;
		}
		
		try {
			basePortrait = Image.createImage("/res/graphics/minglet-still.png");
		}
		catch(IOException e) {
			basePortrait = null;
		}
		
	}
	
	public void paint(Graphics g) {
		if(!active) return;
		
		Font f = g.getFont();
		g.setFont(JMingle.DEFAULT_FONT);
		g.setColor(0xFFFFFF);
		g.fillRoundRect(x, y, width, height, width / 10, height / 10);
		g.setColor(0);
		g.drawRoundRect(x, y, width, height, width / 10, height / 10);
		
		
		if(isEmpty()) {
			g.drawString("Your Mingle book is empty!", x + width / 2, y + height / 2, Graphics.BOTTOM | Graphics.HCENTER);
			g.setFont(f);
			return;
		}
		
		if(subject == null) {
			subject = getPortrait();
		}
		
		if(friendlyLastSeen == null || friendlyLastSeen.length() == 0) {
			friendlyLastSeen = getLastSeenTime();
		}
		

		int a = x + width / 2;
		int b = y + height / 4 + subject.getHeight() / 2;
		g.drawImage(subject, a, b, Graphics.HCENTER | Graphics.BOTTOM);
		
		int fontHeight = g.getFont().getHeight();
		int startPoint = (y + ((3 * height) / 4) + ((3 * g.getFont().getHeight())) / 2);
		
		// TODO: I think calling getName() and getOwner() so much is a bad idea in a paint() function. Maybe caching would be good.
		g.drawString("Name: " + getName(), x + width / 2, startPoint - 2 * fontHeight, Graphics.BOTTOM | Graphics.HCENTER);
		g.drawString("Owner: " + getOwner(), x + width / 2, startPoint - fontHeight, Graphics.BOTTOM | Graphics.HCENTER);
		g.drawString("Last seen: " + friendlyLastSeen, x + width / 2, startPoint, Graphics.BOTTOM | Graphics.HCENTER);
		
		// Paint the arrows
		if(hasNext()) {
			if(arrowRight != null) {
				g.drawImage(arrowRight, x + width - 3, y + height / 2, Graphics.RIGHT | Graphics.VCENTER);
			}
			else {
				g.drawString(">>", x + width - 3, y + height / 2, Graphics.RIGHT | Graphics.BASELINE);
			}
		}
			
		if(hasPrevious()) {
			if(arrowLeft != null) {
				g.drawImage(arrowLeft, x + 3, y + height / 2, Graphics.LEFT | Graphics.VCENTER);
			}
			else {
				g.drawString("<<", x + 3, y + height / 2, Graphics.LEFT | Graphics.BASELINE);
			}
		}
		
		g.setFont(f);
	}
	
	public void addSubject(Actor a) {
		// TODO: This is slow!
		// We'd like to find a better way to do this some time!
		subjects.addElement( Utils.makeActor(a.getAddress(), a.getOwner(), a.getLastSeen()) );
	}
	
	public void clear() {
		subjects.removeAllElements();
		tracker = null;
		subject = null;
		friendlyLastSeen = null;
		elementIndex = 0;
	}
	
	public void next() {
		if(hasNext()) {
			elementIndex++;
			friendlyLastSeen = null;
			subject = null;
		}
	}
	
	public void previous() {
		if(hasPrevious()) {
			elementIndex--;
			subject = null;
			friendlyLastSeen = null;
		}
	}
	
	public boolean hasNext() {
		if(tracker != null) {
			return elementIndex < tracker.numberOfDevices() - 1;
		}
		else {
			return elementIndex < subjects.size() - 1;
		}
	}
	
	public boolean hasPrevious() {
		return elementIndex > 0;
	}
	

	
	public void setTracker(MingleTracker t) {
		clear();
		tracker = t;
	}
	
	public void setActive(boolean b) {
		active = b;
	}
	
	public boolean isActive() {
		return active;
	}
	
	public Image getPortrait() {		
		if(tracker == null) {
			Actor a = (Actor) subjects.elementAt(elementIndex);
			return Utils.customizeMinglet(basePortrait, a.getAddress());
		}
		
		MingleNode n = tracker.deviceAt(elementIndex);
		return Utils.customizeMinglet(basePortrait, n.getAddress());
	}
	
	public String getName() {
		if(tracker == null) {
			Actor a = (Actor) subjects.elementAt(elementIndex);
			return a.getName();
		}
		
		MingleNode n = tracker.deviceAt(elementIndex);
		return Utils.makeName( Utils.hexToDecimal(n.getAddress()) );
	}
	
	public String getOwner() {
		if(tracker == null) {
			Actor a = (Actor) subjects.elementAt(elementIndex);
			return a.getOwner();
		}
		
		MingleNode n = tracker.deviceAt(elementIndex);
		return n.getName();
	}
	
	public String getLastSeenTime() {
		if(tracker == null) {	
			Actor a = (Actor) subjects.elementAt(elementIndex);
			return Utils.friendlyTimeDiffNow(a.getLastSeen());
		}

		MingleNode n = tracker.deviceAt(elementIndex);
		return Utils.friendlyTimeDiffNow(n.getLastSeen());
	}
	
	public boolean isEmpty() {
		if(tracker == null) {
			return subjects.size() == 0;
		}
		return tracker.numberOfDevices() == 0;
	}

}
